/*
 * @Author: your name
 * @Date: 2021-10-14 13:54:26
 * @LastEditTime: 2021-10-19 09:13:06
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \web-maps\src\util\color\util.ts
 */
import  { rgb, interpolate, scaleLinear, RGBColor } from "d3";

 const compute = (startColor: RGBColor, endColor: RGBColor) => interpolate(startColor, endColor);

 const linear = (min:number, max:number) => scaleLinear().domain([min, max]);

 const COLOR_LEN = 256;

/**
 * @description rgb 转 16进制  rgb(255,255,255) => #ffffff
 * @param color rgb颜色
 * @returns 16进制颜色
 */
const colorRgbToHex = function (color: string): string {
  if (/^(rgb|RGB)/.test(color)) {
    const [r, g, b] = color.replace(/(?:\(|\)|rgb|RGB)*/g, "").split(",");

    /**
     * @see https://zhuanlan.zhihu.com/p/339012370
     */
    return (
      "#" +
      ((1 << 24) + (Number(r) << 16) + (Number(g) << 8) + Number(b))
        .toString(16)
        .slice(1)
    );
  }

  console.warn("[COLOR_ERROR]: 请输入一个正确的rgb格式的颜色");

  return "#00000";
};

 /**
  * @description  16进制转 rgb
  * @param color 16进制格式的颜色样式
  * @returns rgb
  */
const colorHexToRgb = function (color: string): string {
  let _color = color.toLowerCase();

  if (/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(color)) {
    if (_color.length === 4) {
      _color = _color.slice().concat(..._color.slice(1));
    }

    const transform = function (start:number, end:number): number {
      return Number.parseInt("0x" + _color.slice(start, end));
    };

    return `rgb(${transform(1, 3)},${transform(3, 5)},${transform(5, 7)})`;
  }

  console.warn("[COLOR_ERROR]: 请输入一个正确的16进制格式的颜色");

  return "rgb(255,255,255)";
};

/**
 * @see https://github.com/d3/d3-scale-chromatic/blob/main/src/sequential-multi/viridis.js
 * @description 渐变函数
 * @param range 范围
 * @returns 归一化函数
 */
const ramp = function (range:string[]) {
  var n = range.length;
  return function (t:number) {
    return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];
  };
};

/**
 * @see https://github.com/d3/d3-scale-chromatic/blob/main/src/colors.js
 * @description 颜色组装函数
 * @param specifier 颜色字符串集合
 * @returns
 */
const colorCombine = function (specifier:string) {
  var n = (specifier.length / 6) | 0,
    colors:string[] = new Array(n),
    i = 0;

  while (i < n) colors[i] = "#" + specifier.slice(i * 6, ++i * 6);
  return colors;
};

const transformColors = function (sourceColors:any[],isShortfall=true){
  const _hexColor: string[] = [];

  const r = ~~(COLOR_LEN / sourceColors.length);

  for (let i = 0; i < sourceColors.length; i++) {

    const startColor = rgb(sourceColors[i]);
    const endColor = rgb(sourceColors[i + 1]);

    for (let j = 0; j < r; j++) {
      _hexColor.push(
        colorRgbToHex(compute(startColor, endColor)(linear(0, r)(j))).slice(1)
      );
    }
  }

  // 补充成 256长度
  if(isShortfall){
    for (let z = 0, len = COLOR_LEN - _hexColor.length; z < len; z++) {
      _hexColor.push(_hexColor[_hexColor.length - 1]);
    }
  }


  // console.log(_hexColor);

  return ramp(colorCombine(_hexColor.join("")));
}

export { colorHexToRgb, colorRgbToHex, transformColors };
